#include <stdio.h>

#include "user_threads.h"
#include "user_mutex.h"
#include "user_io.h"

int global = 0;

int benchmarkFunction(void* pipePtr) {
//	printf("my id is %d\n",uthread_self());
	if (!pipePtr) {
		return -1;
	}
	int* fileDescs = (int*)pipePtr;
	int ownTid = uthread_self();
	int i;
	for (i=0; i<10; ++i) {
		int globalValue = global;
		int dataFromPipe;
		int readRes = uthread_read(fileDescs[0], &dataFromPipe, sizeof(dataFromPipe)); // 0 is read end
//		printf("after read\n");
		if (!readRes) {
			printf("Error in read from pipe. Thread Id: %d\n", ownTid);
			return -1;
		}
		printf("Thread Id=%d global=%d got from pipe %d\n", ownTid, globalValue, dataFromPipe);
		global++;
		int writeRes = uthread_write(fileDescs[1], &ownTid, sizeof(ownTid));
		if (!writeRes) {
			printf("Error in write to pipe. Thread Id: %d\n", ownTid);
			return -1;
		}
		uthread_yield();
	}
	return 0;
}

int main() {
	int threads[19];
	int testPipe[2];
	
	if (uthread_init() != UTHREAD_SUCCESS) {
		printf("Failed to initialize uthread library\n");
		return -1;
	}
	
	if (uthread_pipe(testPipe) != 0) {
		printf("Failed to create pipe\n");
		return -1;
	}
	int i;
	for (i=0; i<19; ++i) {
		threads[i] = uthread_create(benchmarkFunction, testPipe, 6);
		if (threads[i] == UTHREAD_FAIL) {
			printf("Failed to create thread\n");
			return -1;
		}
	}
	uthread_write(testPipe[1],"0",1);
	uthread_yield();
	benchmarkFunction(testPipe);
//	printf("is 0 stuck?\n");
	for (i=0; i<19; ++i) {
		int threadReturnVal;
		int joinRes = uthread_join(threads[i],&threadReturnVal);
		if (joinRes==UTHREAD_SUCCESS) {
			printf("Thread %d exited successfully with return value %d\n", threads[i], threadReturnVal);
		}
		else {
			printf("Failed to join thread %d. Reason: %d\n",threads[i], joinRes);
			return -1;
		}
	}	
	return 0;
}
